package com.study.kt._03coroutines

import kotlinx.coroutines.*
import java.lang.Exception
import java.lang.RuntimeException
import kotlin.system.measureTimeMillis

/**
 * <pre>
 *     author : xxs
 *     time   : 2020/12/30
 *     desc   :
 * </pre>
 */
fun main() {
    //test1()
    //test2()
    test3()
}

// 协程的取消会沿着协程层次体系向上传播
fun test3() = runBlocking {
    try {
        testException()
    } finally {
        println("test3 finally")
    }
}

fun test2() = runBlocking {
    val time = measureTimeMillis {
        println(valueResult())
    }
    println("time=$time")
}

fun test1() {
    // 使用GlobalScope.async+挂起函数 就和调用普通函数类似
    val v3 = intValue3Async()
    val v4 = intValue4Async()
    // 此处出现异常，无法停止协程运行，所以不推荐该做法
    val i = 1 / 0
    runBlocking {
        println("result=${v3.await() + v4.await()}")
    }
}

suspend fun intValue3(): Int {
    delay(1000)
    println("intValue3")
    return 100
}

suspend fun intValue4(): Int {
    delay(2000)
    println("intValue4")
    return 200
}

fun intValue3Async() = GlobalScope.async {
    intValue3()
}

fun intValue4Async() = GlobalScope.async {
    intValue4()
}

suspend fun valueResult(): Int = coroutineScope {
    val v3 = async { intValue3() }
    val v4 = async { intValue4() }
    v3.await() + v4.await()
}

suspend fun testException(): Int = coroutineScope {
    val value1 = async<Int> {
        try {
            delay(5000)
            10
        } finally {
            println("value1 finally")
        }
    }
    // 此处遇到异常，网上传递value1正在执行的耗时任务也会停止
    val value2 = async<Int> {
        println("value2 throw exception")
        throw Exception("value2 exception。。。。")
    }

    value1.await() + value2.await()
}